﻿using System.Collections.Generic;
using Cms.Application.Admin.Views;
using Cms.Application.IO;
using Cms.Data;
using Cms.Domain;
using Cms.Domain.RepositoryInterfaces;
using iLib.Web.UI;

namespace Cms.Application.Admin.Presenters
{
    public class EditPluginTemplatePresenter : BasePresenter
    {
        private readonly Administrator _administrator;
        private readonly IEditPluginTemplateView _view;
        public IDiskAccess DiskAccess;

        public EditPluginTemplatePresenter(IEditPluginTemplateView view)
            : this(view, new RepositoryFactory())
        {
            DiskAccess = new DiskAccess();
        }

        public EditPluginTemplatePresenter(IEditPluginTemplateView view, IRepositoryFactory repositoryFactory)
            : base(view, repositoryFactory)
        {
            _view = view;
            _administrator = AdministratorRepository.GetAdministrator(_view.AdministratorID);
            if (!_administrator.HasPermission.EditPluginTemplate)
                _view.RedirectToPermissionDeniedPage();
        }
        
        public void Initialize()
        {
            if (_view.TemplateID > 0)
            {
                PluginTemplate template = SystemRepository.GetPluginTemplate(_view.TemplateID);
                _view.Name = template.Name;
                _view.Description = template.Description;
                _view.SourceCode = template.GetCode();
                _view.PluginID = template.Plugin.ID;
            }
            else
            {
                Plugin plugin = SystemRepository.GetPlugin(_view.PluginID);
                _view.SourceCode =
                    DiskAccess.ReadTextFile("Admin\\Resources\\PluginTemplates\\" + plugin.GetClassName() + ".ascx");
            }
        }

        public void Save()
        {
            if (_view.Name.Trim() == "")
                AddValidationError(GetText(_view, "NoNameError"));
            if (_view.SourceCode.Trim() == "")
                AddValidationError(GetText(_view, "NoSourceCodeError"));
            /*
            string sourceCodeValidationResult = _view.GetSourceCodeStatus();
            if (sourceCodeValidationResult != "ok")
            {
                string errorText = GetText(_view, "SourceCodeError");
                errorText = errorText.Replace("[[ErrorMessage]]", sourceCodeValidationResult);
                string encryptedCredentials = Cms.Application.Cipher.Encrypt(_administrator.Username + (char)9 + _administrator.Password);
                string url = iLib.Web.UI.Url.FullPath + "Admin/Default.aspx?credentials=" +
                                HttpUtility.UrlEncode(encryptedCredentials) + "&ReturnUrl=" +
                                HttpUtility.UrlEncode(_view.UserTempDirectory + "ErrorDetails.aspx?v=" + DateTime.Now.Ticks);
                errorText = errorText.Replace("[[ErrorDetailsUrl]]", url);
                this.AddValidationError(errorText);
            }
            */
            if (!IsValid)
                return;
            var plugin = (TemplatablePlugin)SystemRepository.GetPlugin(_view.PluginID);
            PluginTemplate template;
            if (_view.TemplateID == -1)
            {
                template = new PluginTemplate();
                template.Site = _administrator.CurrentSite;
                template.Plugin = plugin;
                plugin.Templates.Add(template);
            }
            else
            {
                template = SystemRepository.GetPluginTemplate(_view.TemplateID);
            }
            template.Name = _view.Name;
            template.Description = _view.Description;
            template.SetCode(_view.SourceCode, _administrator);
            SystemRepository.SavePlugin(plugin);
            DiskAccess.DeleteFile("__System\\PluginTemplates\\" + template.ID + ".ascx");
            DiskAccess.CreateDirectory("__System\\PluginTemplates");
            DiskAccess.CreateTextFile("__System\\PluginTemplates\\" + template.ID + ".ascx", _view.SourceCode);
            _view.SetTemplateID(template.ID);
        }

        public void UpdateLiterals()
        {
            PluginTemplate template = SystemRepository.GetPluginTemplate(_view.TemplateID);
            IList<PluginTemplateLiteral> literals = _view.GetPluginLiterals(Url.VirtualPath +
                                                                            "__System\\PluginTemplates\\" + template.ID +
                                                                            ".ascx");

            // Remove literals from the database if they cannot be found in the UserControl
            IList<PluginTemplateLiteral> delete = new List<PluginTemplateLiteral>();
            foreach (PluginTemplateLiteral dbLiteral in template.Literals)
            {
                bool found = false;
                foreach (PluginTemplateLiteral ucLiteral in literals)
                {
                    if (dbLiteral.ControlID.ToLower() == ucLiteral.ControlID.ToLower())
                    {
                        found = true;
                        break;
                    }
                }
                if (!found)
                {
                    delete.Add(dbLiteral);
                }
            }
            foreach (PluginTemplateLiteral literal in delete)
            {
                literal.Template.Literals.Remove(literal);
                literal.Template = null;
            }
            // Add literals from the UserControl and update existing
            foreach (PluginTemplateLiteral ucLiteral in literals)
            {
                bool found = false;
                foreach (PluginTemplateLiteral dbLiteral in template.Literals)
                {
                    if (ucLiteral.ControlID.ToLower() == dbLiteral.ControlID.ToLower())
                    {
                        found = true;
                        // Update properties
                        break;
                    }
                }
                if (!found)
                {
                    ucLiteral.Template = template;
                    template.Literals.Add(ucLiteral);
                }
            }
            SystemRepository.SavePlugin(template.Plugin);
        }
    }
}